package tinsiec;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.Vector;

public class NetworkConfig
{
    private static NetworkInterface selectedInterface;
    private static InetAddress localAddress;

    private static Vector<INetworkConfigListener> listeners = new Vector<INetworkConfigListener>();

    public interface INetworkConfigListener
    {
        void onInterfaceChanged(NetworkInterface newInterface);
    }

    public static void addListener(INetworkConfigListener listener)
    {
        if(listeners.contains(listener) == false)
            listeners.add(listener);
    }

    public static void removeListener(INetworkConfigListener listener)
    {
        listeners.remove(listener);
    }

    private static void fireInterfaceChanged()
    {
        for(INetworkConfigListener listener : listeners)
            listener.onInterfaceChanged(selectedInterface);
    }

    /**
     @return dostępne interfejsy sieciowe
     */
    public static Enumeration<NetworkInterface> getAvailableInterfaces()
    {
        try
        {
            return NetworkInterface.getNetworkInterfaces();
        }
        catch(SocketException ex)
        {
            ex.printStackTrace();
            return null;
        }
    }

    /**
     Ustawia aktywny interfejs. Jeśli wybrany interfejs jest nieprawidłowy
     wyrzuca wyjątek NullPointerException
     @param iface wybrany interfejs
     */
    public static void setSelectedInterface(NetworkInterface iface)
    {
        if(iface == null)
            throw new NullPointerException("Interfejs nie może zostać ustawiony na null.");
        if(iface == selectedInterface)
            return;
        NetworkInterface temp = selectedInterface;
        selectedInterface = iface;
        localAddress = null;

        Enumeration<InetAddress> addresses = selectedInterface.getInetAddresses();
        InetAddress address;
        while(addresses.hasMoreElements())
        {
            address = addresses.nextElement();
            if(address instanceof Inet4Address)
                localAddress = address;
        }
        if(localAddress == null)
        {
            selectedInterface = temp;
            throw new NullPointerException("Nie udało się ustalić adresu IP dla wybranego interfejsu.");
        }
        fireInterfaceChanged();
    }

    /**
     Zwraca wybrany interfejs.
     @return iface
     */
    public static NetworkInterface getSelectedInterface()
    {
        return selectedInterface;
    }

    /**
     Zwraca adres komputera, który jest używany do komunikacji.s
     @return adres
     */
    public static InetAddress getLocalAddress()
    {
        return localAddress;
    }

    /**
     Zwraca string zawierający adres IP komputera.
     @return adres IP
     */
    public static String getLocalIP()
    {
        if(localAddress == null)
            return "";
        else
            return localAddress.getHostAddress();
    }
}
